import axios, { AxiosError } from "axios";
import type { AxiosResponse, InternalAxiosRequestConfig } from "axios";
import type {
  LoginRequest,
  LoginResponse,
  RegisterRequest,
  FamilyMemberResponse,
  Token,
  ChangePasswordRequest,
} from "@/types/auth";
import { api, API_BASE_URL } from "./api";

// 响应拦截器 - 处理 token 过期
api.interceptors.response.use(
  (response: AxiosResponse) => response,
  async (error: AxiosError) => {
    const originalRequest = error.config as InternalAxiosRequestConfig & {
      _retry?: boolean;
    };

    // 如果是 401 错误且不是刷新 token 的请求
    if (error.response?.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;

      try {
        // 尝试刷新 token
        const refreshToken = localStorage.getItem("refresh_token");
        if (refreshToken) {
          const response = await refreshTokenApi(refreshToken);
          const { access_token } = response;

          // 保存新的 token
          localStorage.setItem("access_token", access_token);

          // 重新发送原始请求
          originalRequest.headers.Authorization = `Bearer ${access_token}`;
          return api(originalRequest);
        }
      } catch (refreshError) {
        // 刷新 token 失败，清除本地存储并触发登录事件
        localStorage.removeItem("access_token");
        localStorage.removeItem("refresh_token");
        localStorage.removeItem("user");
        
        // 触发显示登录模态框事件
        const event = new CustomEvent("auth-required");
        window.dispatchEvent(event);
        
        return Promise.reject(refreshError);
      }
    }

    return Promise.reject(error);
  },
);

// 认证相关 API
export const authApi = {
  // 登录
  login: async (data: LoginRequest): Promise<LoginResponse> => {
    const response = await api.post<LoginResponse>("/api/v1/auth/login", data);
    return response.data;
  },

  // 注册
  register: async (data: RegisterRequest): Promise<FamilyMemberResponse> => {
    const response = await api.post<FamilyMemberResponse>(
      "/api/v1/auth/register",
      data,
    );
    return response.data;
  },

  // 验证 token
  verifyToken: async (): Promise<FamilyMemberResponse> => {
    const response = await api.post<FamilyMemberResponse>(
      "/api/v1/auth/verify-token",
    );
    return response.data;
  },

  // 刷新 token
  refreshToken: async (): Promise<Token> => {
    const response = await api.post<Token>("/api/v1/auth/refresh-token");
    return response.data;
  },

  // 登出
  logout: async (): Promise<void> => {
    await api.post("/api/v1/auth/logout");
  },

  // 修改密码
  changePassword: async (data: ChangePasswordRequest): Promise<void> => {
    await api.post("/api/v1/auth/change-password", data);
  },
};

// 刷新 token 的独立函数
export const refreshTokenApi = async (refreshToken: string): Promise<Token> => {
  const baseURL = API_BASE_URL || window.location.origin;
  const response = await axios.post<Token>(
    `${baseURL}/api/v1/auth/refresh-token`,
    {},
    {
      headers: {
        Authorization: `Bearer ${refreshToken}`,
        "Content-Type": "application/json",
      },
    },
  );
  return response.data;
};

// 认证状态管理
export const authService = {
  // 保存认证信息
  saveAuth: (loginResponse: LoginResponse, rememberMe: boolean = false) => {
    const { access_token, token_type } = loginResponse;

    if (rememberMe) {
      localStorage.setItem("access_token", access_token);
      localStorage.setItem("token_type", token_type);
    } else {
      sessionStorage.setItem("access_token", access_token);
      sessionStorage.setItem("token_type", token_type);
    }

    // 保存用户信息
    localStorage.setItem("user", JSON.stringify(loginResponse.family_member));
  },

  // 获取认证 token
  getToken: (): string | null => {
    return (
      localStorage.getItem("access_token") ||
      sessionStorage.getItem("access_token")
    );
  },

  // 获取用户信息
  getUser: (): FamilyMemberResponse | null => {
    const userStr = localStorage.getItem("user");
    return userStr ? JSON.parse(userStr) : null;
  },

  // 检查是否已认证
  isAuthenticated: (): boolean => {
    return !!authService.getToken();
  },

  // 清除认证信息
  clearAuth: () => {
    localStorage.removeItem("access_token");
    localStorage.removeItem("refresh_token");
    localStorage.removeItem("token_type");
    localStorage.removeItem("user");
    sessionStorage.removeItem("access_token");
    sessionStorage.removeItem("token_type");
  },

  // 检查用户角色
  hasRole: (role: string): boolean => {
    const user = authService.getUser();
    return user?.role === role;
  },

  // 检查是否是管理员
  isAdmin: (): boolean => {
    return authService.hasRole("admin");
  },
};

// 错误处理工具函数
export const handleAuthError = (error: unknown): string => {
  if (error instanceof Error) {
    const axiosError = error as AxiosError;
    if (axiosError.response?.data) {
      const data = axiosError.response.data as { detail?: unknown };

      if (data.detail) {
        // 如果是数组形式的验证错误
        if (Array.isArray(data.detail)) {
          return data.detail
            .map((item: unknown) => {
              if (typeof item === "object" && item !== null && "msg" in item) {
                return (item as { msg: string }).msg;
              }
              return String(item);
            })
            .join(", ");
        }

        // 如果是字符串形式的错误消息
        if (typeof data.detail === "string") {
          return data.detail;
        }
      }
    }

    return error.message || "操作失败，请重试";
  }

  return "操作失败，请重试";
};

// 表单验证工具函数
export const validateLoginForm = (data: Partial<LoginRequest>): string[] => {
  const errors: string[] = [];

  if (!data.username) {
    errors.push("用户名不能为空");
  }

  if (!data.password) {
    errors.push("密码不能为空");
  }

  return errors;
};

export const validateRegisterForm = (
  data: Partial<RegisterRequest>,
): string[] => {
  const errors: string[] = [];

  if (!data.username) {
    errors.push("用户名不能为空");
  } else if (data.username.length < 3) {
    errors.push("用户名至少需要3个字符");
  }

  if (!data.email) {
    errors.push("邮箱不能为空");
  } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
    errors.push("邮箱格式不正确");
  }

  if (!data.password) {
    errors.push("密码不能为空");
  } else if (data.password.length < 6) {
    errors.push("密码至少需要6个字符");
  }

  if (!data.full_name) {
    errors.push("姓名不能为空");
  }

  if (!data.family_name) {
    errors.push("家庭名称不能为空");
  }

  return errors;
};

export default api;
